package cz.muni.fi.pa165.musiclibrary.impl.database.dao;

import java.util.List;

import javax.annotation.Nonnull;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;

import cz.muni.fi.pa165.musiclibrary.impl.database.entity.IGenre;
import cz.muni.fi.pa165.musiclibrary.impl.database.entity.Genre;

/**
*
* @author Martin Majlath
* @date 2012-10-13T19:22:20+0200
*/
@Repository
public class GenreDAO extends AbstractDAO implements IGenreDAO{
    /**
     * Entity manager.
     */
    private EntityManager entityManager;

    /**
     * Inject {@link EntityManager} instance;
     */
    @PersistenceContext
    @Required
    @Override
    public void setEntityManager(final EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    
    @Override
    public void create(@Nonnull final IGenre genre) throws DataAccessException {
        Validate.isTrue(genre != null, "Genre should not be null.");
        Validate.isTrue(genre.getIdGenre() == null, "Genre identifier should be null.");
        Validate.isTrue(genre.getName() != null, "Genre name should not be null.");
        
        this.entityManager.persist(genre);
    }

    @Override
    public void update(@Nonnull final IGenre genre) throws DataAccessException {
        Validate.isTrue(genre != null, "Genre should not be null.");
        Validate.isTrue(genre.getIdGenre() != null, "Genre identifier should not be null.");
        Validate.isTrue(genre.getName() != null, "Genre name should not be null.");
        
        final Query update = this.entityManager.createQuery("UPDATE Genre g SET g.name = :name WHERE g.id_genre = :id_genre");
        update.setParameter("name", genre.getName())//
                .setParameter("id_genre", genre.getIdGenre());
        update.executeUpdate();
    }

    @Override
    public void delete(@Nonnull final IGenre genre) throws DataAccessException {
        Validate.isTrue(genre != null, "Genre should not be null.");
        Validate.isTrue(genre.getIdGenre() != null, "Genre identifier should not be null.");
        Validate.isTrue(genre.getName() != null, "Genre name should not be null.");
        
        final Query delete = this.entityManager.createQuery("DELETE FROM Genre g WHERE g.id_genre = :id_genre");
        delete.setParameter("id_genre", genre.getIdGenre());
        delete.executeUpdate();
    }

    @Override
    public IGenre getById(Long idGenre) throws DataAccessException {
        Validate.isTrue(idGenre != null, "Identifier should not be null.");
        final Genre genre = this.entityManager.find(Genre.class, idGenre);
        return genre;
    }

    @Override
    public List<IGenre> getAll() throws DataAccessException {
        final List<IGenre> genres = this.entityManager.createQuery("SELECT g FROM Genre g").getResultList();
        return genres;
    }

}